/*
us * NOTE: This copyright does *not* cover user programs that use HQ
* program services by normal system calls through the application
* program interfaces provided as part of the Hyperic Plug-in Development
* Kit or the Hyperic Client Development Kit - this is merely considered
* normal use of the program, and does *not* fall under the heading of
* "derived work".
*
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
* This file is part of HQ.
*
* HQ is free software; you can redistribute it and/or modify
* it under the terms version 2 of the GNU General Public License as
* published by the Free Software Foundation. This program is distributed
* in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
package org.hyperic.hq.authz.server.session;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.hibernate.SessionFactory;
import org.hyperic.hq.authz.shared.AuthzConstants;
import org.hyperic.hq.dao.HibernateDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
@Repository
public class OperationDAO
extends HibernateDAO<Operation> {
private JdbcTemplate jdbcTemplate;
private static final String OPERABLE_SQL =
/* ex. "SELECT DISTINCT(server_type_id) FROM eam_server " + */
" s, EAM_CONFIG_RESPONSE c, EAM_RESOURCE r, EAM_OPERATION o, "
+ "EAM_RESOURCE_TYPE t, EAM_ROLE_OPERATION_MAP ro, " + "EAM_ROLE_RESOURCE_GROUP_MAP g, "
+ "EAM_RES_GRP_RES_MAP rg "
+ "WHERE t.name = ? AND o.resource_type_id = t.id AND o.name = ? AND "
+ "operation_id = o.id AND ro.role_id = g.role_id AND "
+ "g.resource_group_id = rg.resource_group_id AND "
+ "rg.resource_id = r.id AND r.resource_type_id = t.id AND "
+ "r.instance_id = s.id AND s.config_response_id = c.id AND "
+ "c.control_response is not null AND " + "(r.subject_id = ? OR EXISTS "
+ "(SELECT * FROM EAM_SUBJECT_ROLE_MAP sr "
+ "WHERE sr.role_id = g.role_id AND subject_id = ?))";
@Autowired
public OperationDAO(SessionFactory f, JdbcTemplate jdbcTemplate) {
super(Operation.class, f);
this.jdbcTemplate = jdbcTemplate;
}
public Operation getByName(String name) {
String sql = "from Operation where name = :name";
return (Operation) getSession().createQuery(sql).setParameter("name", name).uniqueResult();
}
public Operation findByTypeAndName(ResourceType type, String name) {
String sql = "from Operation where resourceType=? and name=?";
return (Operation) getSession().createQuery(sql).setParameter(0, type).setString(1, name)
.setCacheable(true).setCacheRegion("Operation.findByTypeAndName").uniqueResult();
}
@SuppressWarnings("unchecked")
public Collection<Integer> findViewableOperationIds(Collection<ResourceType> resourceTypes) {
// adding this due to bug in hibernate-https://hibernate.atlassian.net/browse/HHH-2045
// our bug-https://jira.hyperic.com/browse/HQ-4479
if ((resourceTypes == null) || resourceTypes.isEmpty()) {
return Collections.emptyList();
}
String sql = "from Operation where resourceType in (:types) and name like '+view+%'";
sql = sql.replace("+view+", AuthzConstants.VIEW_PREFIX);
final List<Operation> list = getSession().createQuery(sql).setParameterList("types", resourceTypes).list();
final List<Integer> rtn = new ArrayList<Integer>(list.size());
for (Operation o : list) {
rtn.add(o.getId());
}
return rtn;
}
@SuppressWarnings("unchecked")
public Collection<Operation> findByResourceType(Collection<ResourceType> resourceTypes) {
// adding this due to bug in hibernate-https://hibernate.atlassian.net/browse/HHH-2045
if ((resourceTypes == null) || resourceTypes.isEmpty()) {
return Collections.emptyList();
}
String sql = "from Operation where resourceType in (:types)";
return getSession().createQuery(sql).setParameterList("types", resourceTypes).list();
}
@SuppressWarnings("unchecked")
public Collection<Role> findByRole(Integer roleId) {
String sql = "select o from Role r join r.operations o where r.id = ?";
return getSession().createQuery(sql).setParameter(0, roleId).list();
}
public List<Integer> findOperableResourceIds(final AuthzSubject subj,
final String resourceTable,
final String resourceColumn, final String resType,
final String operation, final String addCond) {
final StringBuffer sql = new StringBuffer("SELECT DISTINCT(s.").append(resourceColumn)
.append(") FROM ").append(resourceTable).append(OPERABLE_SQL);
if (addCond != null) {
sql.append(" AND s.").append(addCond);
}
List<Integer> resTypeIds = this.jdbcTemplate.query(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement stmt = con.prepareStatement(sql.toString());
int i = 1;
stmt.setString(i++, resType);
stmt.setString(i++, operation);
stmt.setInt(i++, subj.getId().intValue());
stmt.setInt(i++, subj.getId().intValue());
return stmt;
}
}, new RowMapper<Integer>() {
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getInt(1);
}
});
return resTypeIds;
}
public boolean userHasOperation(AuthzSubject subj, Operation op) {
String hql = new StringBuilder(128).append("select 1 from Role r ").append(
"join r.operations op ").append("join r.subjects s ").append(
"where s = :subject and op = :operation").toString();
return getSession().createQuery(hql)
.setParameter("subject", subj)
.setParameter("operation", op)
.list().size() > 0;
}
}